package com.etone.smartAudit.apiIntercept;

import cn.hutool.core.util.StrUtil;
import com.etone.smartAudit.domain.AppManager;
import com.etone.smartAudit.filter.TokenFilter;
import com.etone.smartAudit.security.SecurityUtils;
import com.etone.smartAudit.security.jwt.TokenProvider;
import com.etone.smartAudit.service.AdminService;
import com.etone.smartAudit.service.AppManagerService;
import com.etone.smartAudit.utils.Md5Util;
import com.etone.smartFlow.common.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.util.*;
import java.util.stream.Collectors;

/***
 * api 校验签名
 */
@Slf4j
@Component
public class ApiConfig {


    @Autowired
    private AppManagerService appManagerService;

    @Autowired
    private TokenProvider tokenProvider;


    /***
     * 校验请求参数
     * @param request
     */
    public Result checkParam(HttpServletRequest request) {


        Map<String, String> params = new TreeMap<>();
        String appId = request.getHeader("appId");
        String sign = request.getHeader("sign");
        String timestamp = request.getHeader("timestamp");
        String token = request.getHeader("Authorization");
        //校验token
        if (StrUtil.isNotEmpty(token)) {
            if (StrUtil.isNotEmpty(token)) {
                return Result.success(null);
            }
            //校验token 是否正确
            String name = tokenProvider.getNameByToken(token);
            if (StrUtil.isNotEmpty(name)) {
                return Result.success(null);
            }

        }

        if (StrUtil.isEmpty(timestamp)) {
            return Result.fail("时间戳参数不能为空");
        } else {
            try {
                Long times = Long.valueOf(timestamp);
                if (System.currentTimeMillis() - times > 60000) {
                    return Result.fail("请求时间已过期");
                }
            } catch (Exception e) {
                return Result.fail("错误的时间戳格式");
            }
        }

        params.put("appId", appId);
        params.put("sign", sign);
        params.put("timestamp", timestamp);

        Enumeration<String> names = request.getParameterNames();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            String value = request.getParameter(name);
            params.put(name, value);
        }
        //执行签名校验
        Result result = checkParam(params);
        return result;
    }


    /**
     * 校验请求参数
     *
     * @param params
     */
    private Result checkParam(Map<String, String> params) {

        String appId = params.get("appId");
        //判断appid是否存在
        Result<String> secretResult = checkAppId(appId);
        if (Result.SUCCESSFUL_CODE.equals(secretResult.getCode())) {
            //添加签名验证参数
            params.put("secret", secretResult.getData());
        } else {
            return secretResult;
        }
        //获取签名参数
        String sign = params.get("sign");
        if (StrUtil.isEmpty(sign)) {
            return Result.fail("签名参数不存在");
        }
        //移除签名参数
        params.remove("sign");

        //组装参数
        String str = params.keySet().stream().map(key -> String.format("%s=%s", key, params.get(key
        ))).collect(Collectors.joining("&"));
        log.info("请求参数:{}", str);
        //执行签名
        String cusSign = DigestUtils.md5Hex(str);

        if (!sign.equals(cusSign)) {
            return Result.fail("签名错误");
        }
        return Result.success("");
    }

    /***
     * 判断appId是否存在 存在返回secrtId
     */
    private Result checkAppId(String appId) {

        if (appId == null) {
            return Result.fail("appid不存在,请填写appId");
        }
        AppManager appManager = appManagerService.getAppManagerByAppId(appId);
        if (appManager == null) {
            return Result.fail("appid不存在,请联系管理员申请");
        }
        return Result.success(appManager.getAppSecrt());
    }


    public static void main(String[] args) {
        String appId = "XRO6U22I";
        Long timestamp = System.currentTimeMillis();
        String appsecrt = "cdz11rbipupjwdfuy4i66dvjmdnd072v";
        Map<String, String> params = new TreeMap<>();
        params.put("appId", appId);
        params.put("timestamp", timestamp.toString());
        params.put("secret", appsecrt);

        //组装参数
        String str = params.keySet().stream().map(key -> String.format("%s=%s", key, params.get(key
        ))).collect(Collectors.joining("&"));
        //执行签名（对组装参数进行MD5加密）
        String url = "appId=XRO6U22I&secret=cdz11rbipupjwdfuy4i66dvjmdnd072v&timestamp=1646213365710&type=1";
        String sign = DigestUtils.md5Hex(url);
        System.out.println(sign);
    }
}
